#include <algorithm>
#include <vector>
#include <typeinfo>
#include <iostream>
#include "bga/system/ResourceLocator.h"
#include "bga/system/Utilities.h"

namespace bga
{

template< typename T >
inline T* MediaManager::loadFromFile(const std::string& filename)
{
    /// Find the media with the resource locator
    //File FileToLoad = ResourceLocator::getInstance().findFile(File(filename));
    File FileToLoad = ResourceLocator::getInstance().findFile(filename);
    //std::string completePath = ResourceLocator::getInstance().findCompletePath(filename);
    std::cout << "> Load " << FileToLoad.getFullName() << std::endl;
    /// Extract the extension
    std::string ext;
    ext = filename.substr(filename.size() - 3);
    Loader<T>* loader = this->findLoader<T>(ext);
    return loader->load(FileToLoad);
}

template< typename T>
inline void MediaManager::registerLoader(Loader<T>* loader, const std::string& extension)
{
    std::vector<std::string> ext;
    Utilities::split(extension, ext, ";-!*$&");

    for(unsigned int i = 0; i < ext.size(); i++)
    {
        for(unsigned int j = 0; j < ext[i].size(); j++)
            ext[i].at(j) = std::tolower(ext[i].at(j));

        MediaHolder<T>::listOfLoaders[ext[i]].reset(loader);
    }

    //std::string ext = extension;


    /// TODO : maybe handle one loader for several formats
    //MediaHolder<T>::listOfLoaders.insert(std::pair< const std::string, Loader<T>* >(ext, loader));
    //MediaHolder<T>::listOfLoaders[ext].reset(loader);
}

template< typename T >
inline Loader<T>* MediaManager::findLoader(const std::string& extension)
{
    std::string ext = extension;
    for(unsigned int i = 0; i < extension.size(); i++)
        ext.at(i) = std::tolower(extension.at(i));

    if(MediaHolder<T>::listOfLoaders.find(ext) != MediaHolder<T>::listOfLoaders.end())
    {
        return MediaHolder<T>::listOfLoaders[ext].get();
    }
    std::string s = "No loader for ";
    s += ext;
    s += " was found";
    throw BoardHellException(s.c_str());
}

}
